package com.yonyou.gmcc.gateway.web.config;

import java.util.Map;

import javax.servlet.DispatcherType;
import javax.servlet.Filter;

import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.authc.AnonymousFilter;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.filter.DelegatingFilterProxy;

import com.google.common.collect.Maps;
import com.yonyou.gmcc.gateway.web.consts.CommonConstants;
import com.yonyou.gmcc.gateway.web.dao.TmResourceMapper;
import com.yonyou.gmcc.gateway.web.shiro.SessionManager;
import com.yonyou.gmcc.gateway.web.shiro.SimpleRoleAuthorizationFilter;
import com.yonyou.gmcc.gateway.web.shiro.TokenDelegatingFilterProxy;
import com.yonyou.gmcc.gateway.web.shiro.TokenShiroFilterFactoryBean;
import com.yonyou.gmcc.gateway.web.shiro.URLPermissionsFilter;
import com.yonyou.gmcc.gateway.web.shiro.UserRealm;

@Configuration
@AutoConfigureAfter(MyBatisMapperScannerConfig.class)
public class ShiroConfig {
	
	
	/** 
     * FilterRegistrationBean 
     * @return 
     */  

    @Bean  
    public FilterRegistrationBean filterRegistrationBean() {  
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();  
        filterRegistration.setFilter(new TokenDelegatingFilterProxy("shiroFilter"));//DelegatingFilterProxy   
        filterRegistration.setEnabled(true);  
        filterRegistration.addUrlPatterns("/*");   
        filterRegistration.setDispatcherTypes(DispatcherType.REQUEST);  
        return filterRegistration;  
    }  
  
    /**  
     * @see org.apache.shiro.spring.web.ShiroFilterFactoryBean  
     * @return  
     */  
    @Bean(name = "shiroFilter")  
    public ShiroFilterFactoryBean shiroFilter(){  
        ShiroFilterFactoryBean bean = new TokenShiroFilterFactoryBean();  
        bean.setSecurityManager(securityManager());  
        //bean.setLoginUrl("/manager/login");  
        bean.setUnauthorizedUrl("/unauthor");  
        
//      filters.put("perms", urlPermissionsFilter());  
//      filters.put("anon", new AnonymousFilter());  
  
        Map<String, Filter>filters = Maps.newHashMap();  
        filters.put("role", new SimpleRoleAuthorizationFilter());
        bean.setFilters(filters);  
        
        Map<String, String> chains = Maps.newHashMap();  
//        chains.put("/manager/login", "anon");  
//        chains.put("/manager/unauthor", "anon");  
//        chains.put("/manager/logout", "logout");  
//        chains.put("/manager/base/**", "anon");  
//        chains.put("/wechatcall/**", "roles[admin]");  
//        //chains.put("/wechatcall/test", "roles[\"admin,super\"]");  
//        chains.put("/wechatcall/test", "role[\"admin,super\"]");  
//        chains.put("/user/edit/**", "perms[admin:edit:*]");  
//        chains.put("/comp/**", "roles[admin]"); 
//        //chains.put("/comp/**", "authc"); 
//        chains.put("/css/**", "anon");  
//        chains.put("/layer/**", "anon");  
//        chains.put("/html/**", "anon");  
////        chains.put("/**", "authc,perms");  
        bean.setFilterChainDefinitionMap(chains);  
        return bean;  
    }  
  
    /**  
     * @see org.apache.shiro.mgt.SecurityManager  
     * @return  
     */  
    @Bean(name="securityManager")  
    public DefaultWebSecurityManager securityManager() {  
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();  
        manager.setRealm(userRealm());  
        manager.setCacheManager(cacheManager());  
        manager.setSessionManager(defaultWebSessionManager());  
        return manager;  
    }  
  
    /** 
     * @see DefaultWebSessionManager 
     * @return 
     */  
    @Bean(name="sessionManager")  
    public DefaultWebSessionManager defaultWebSessionManager() {  
        DefaultWebSessionManager sessionManager = new SessionManager();  //SessionManager
        sessionManager.setCacheManager(cacheManager());  
        sessionManager.setGlobalSessionTimeout(30*60*1000);  //1800000
        sessionManager.setDeleteInvalidSessions(true);  
        sessionManager.setSessionValidationSchedulerEnabled(true);  
        SimpleCookie sessionIdCookie=new SimpleCookie(CommonConstants.COOKIE_NAME);//
        sessionManager.setSessionIdCookie(sessionIdCookie);
        //sessionManager.setDeleteInvalidSessions(true);  
        return sessionManager;  
    }  
  
    /** 
     * @see UserRealm--->AuthorizingRealm 
     * @return 
     */  
    @Bean  
    @DependsOn(value="lifecycleBeanPostProcessor")  
    public UserRealm userRealm() {  
        UserRealm userRealm = new UserRealm();  
        userRealm.setCacheManager(cacheManager());  
        return userRealm;  
    }  
  
    @Bean  
    public URLPermissionsFilter urlPermissionsFilter() {  
        return new URLPermissionsFilter();  
    }  
  
    @Bean  
    public EhCacheManager cacheManager() {  
        EhCacheManager cacheManager = new EhCacheManager();  
        cacheManager.setCacheManagerConfigFile("classpath:ehcache.xml");  
        return cacheManager;  
    }  
  
    @Bean  
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {  
        return new LifecycleBeanPostProcessor();  
    } 
}
